home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Disc to the Future 2
/
Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin
/
MAC
/
THINKC
/
4_0
/
DVIM72-M
/
DVIM72.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-05-18
|
28KB
|
973 lines
/* -*-C-*- dvim72.c */
/*-->dvim72*/
/**********************************************************************/
/******************************* dvim72 *******************************/
/**********************************************************************/
#include "dvihead.h"
#include "gendefs.h"
#include "m72.h"
#include "bitmap.h"
#if OS_THINKC
#include "mac-specific.h"
#include "PrintMgr.h"
#endif
/* #include "main.h" */
/**********************************************************************/
/****************************** main.h *******************************/
/**********************************************************************/
/**********************************************************************/
/*********************** External Definitions ***********************/
/**********************************************************************/
#if KCC_20
#include <file.h>
#endif /* KCC_20 */
#if PCC_20 /* this stuff MUST be first */
#undef tops20 /* to keep definitions alive */
#include <ioctl.h> /* PCC-20 does not have this in */
/* the others */
#include <file.h> /* need for f20open flags and */
/* JSYS stuff */
#define tops20 1 /* define for tops-20 */
#endif /* PCC_20 */
#include "commands.h"
#include <ctype.h>
#include <math.h>
#if OS_UNIX
#if BSD42
#include <sys/ioctl.h> /* need for DVISPOOL in dviterm.h */
#ifndef _NFILE
/* VAX VMS, NMTCC, PCC-20, and HPUX have _NFILE in stdio.h. V7 called
it NFILE, and Posix calls it OPEN_MAX. KCC-20 calls it SYS_OPEN. VAX
4.3BSD and Gould UTX/32 don't define _NFILE in stdio.h; they use
NOFILE from sys/param.h. Sigh.... */
#include <sys/param.h>
#ifdef NOFILE
#define _NFILE NOFILE /* need for gblvars.h */
#else
#define _NFILE MAXOPEN /* use our font limit value */
#endif
#endif
#endif /* BSD42 */
#endif /* OS_UNIX */
#include "gblprocs.h"
#include "gblvars.h"
#if OS_ATARI
long _stksize = 20000L; /* make the stack a bit larger than 2KB */
/* number must be even */
#endif /* OS_ATARI */
/**********************************************************************/
/******************************* main *******************************/
/**********************************************************************/
#if !OS_THINKC
int
main(
#if OS_THINKC
#else
int argc, char *argv[]
#endif
)
{
register int k; /* loop index */
register int file_args; /* count of file arguments */
#if OS_THINKC
int argc;
char *argv[MAX_ARGS];
get_args( &argc, argv );
if (argc < 2) /* no DVI file specified */
exit(0);
printf("THINK C DVIM72-Mac version 0.1b starting.\n");
printf("Printing <%s>.\n", argv[1]);
#endif
(void)strcpy(g_progname, argv[0]); /* save program name */
(void)initglob(); /* do this before argc check! */
#if OS_UNIX | OS_THINKC
/* On Unix, we allow filtering of stdin to stdout */
/* In THINK C, we put up a standard file dialog to get the .dvi file */
#else /* NOT OS_UNIX */
if (argc < 2)
{
(void)usage(stderr);
(void)EXIT(1);
}
#endif /* OS_UNIX */
for (k = 1; k < argc; ++k)
{
if (*argv[k] == '-') /* -switch */
(void)option(argv[k]);
}
if (!quiet)
{
(void)fprintf(stderr,"[TeX82 DVI Translator Version %s]",VERSION_NO);
NEWLINE(stderr);
(void)fprintf(stderr,"[%s]",DEVICE_ID);
NEWLINE(stderr);
}
if (npage == 0) /* no page ranges given, make a large one */
{
page_begin[0] = 1;
page_end[0] = 32767; /* arbitrary large integer */
page_step[0] = 1;
npage = 1;
}
else /* need font defs from postamble if only some pages to be output */
preload = TRUE;
file_args = 0;
for (k = 1; k < argc; ++k)
{
if (*argv[k] != '-') /* must be file argument */
{
file_args++;
(void)dvifile(argc,argv,argv[k]);
}
}
#if OS_UNIX
if (file_args == 0) /* use stdin/stdout instead */
(void)dvifile(argc,argv,"");
#endif
(void)alldone(); /* this will never return */
return (0); /* never executed; avoid compiler warnings */
}
#endif /* !OS_THINKC */
/**********************************************************************/
/**********************************************************************/
/**********************************************************************/
/* #include "abortrun.h" */
/* #include "actfact.h" */
/* #include "alldone.h" */
/* #include "chargf.h" */
/* #include "charpk.h" */
/* #include "charpxl.h" */
/* #include "clrbmap.h" */
/* #include "clrrow.h" */
/* #include "dbgopen.h" */
/*-->devinit*/
/**********************************************************************/
/****************************** devinit *******************************/
/**********************************************************************/
#if OS_THINKC
#else /* not OS_THINKC */
void
devinit(argc,argv) /* initialize device */
int argc;
char *argv[];
{
(void)getbmap();
if (runlengthcode && !quiet)
{
(void)fprintf(stderr,"[Run-length encoding of output file]");
NEWLINE(stderr);
}
}
#endif /* OS_THINKC */
/*-->devterm*/
/**********************************************************************/
/****************************** devterm *******************************/
/**********************************************************************/
void
devterm() /* terminate device */
{
#if OS_THINKC
Close_printer();
#endif
}
/* #include "dispchar.h" */
/* #include "dvifile.h" */
/* #include "dviinit.c" */
/* #include "dviterm.h" */
/* #include "f20open.h" */
/* #include "fatal.h" */
/* #include "fillrect.h" */
/* #include "findpost.h" */
/* #include "fixpos.h" */
/* #include "fontfile.h" */
/* #include "fontsub.h" */
/* #include "getbmap.h" */
/* #include "getbytes.h" */
/* #include "getfntdf.h" */
/* #include "getpgtab.h" */
/* #include "inch.h" */
/* #include "initglob.h" */
/* #include "loadchar.h" */
/*-->makechar*/
/**********************************************************************/
/****************************** makechar ******************************/
/**********************************************************************/
char
makechar(p,mask)
register UNSIGN32* p[];
register UNSIGN32 mask;
{
register char c;
#if SEGMEM
#define Q(n) p[n] /* use precomputed pointers */
#else /* NOT SEGMEM */
#define Q(n) (p[0] - (n)*XBIT) /* compute pointers on the fly */
#endif /* SEGMEM */
c = '\000';
#if HIRES
if (*Q(0) & mask)
c |= '\001';
if (*Q(2) & mask)
c |= '\002';
if (*Q(4) & mask)
c |= '\004';
if (*Q(6) & mask)
c |= '\010';
if (*Q(8) & mask)
c |= '\020';
if (*Q(10) & mask)
c |= '\040';
if (*Q(12) & mask)
c |= '\100';
if (*Q(14) & mask)
c |= '\200';
#else
if (*Q(0) & mask)
c |= '\001';
if (*Q(1) & mask)
c |= '\002';
if (*Q(2) & mask)
c |= '\004';
if (*Q(3) & mask)
c |= '\010';
if (*Q(4) & mask)
c |= '\020';
if (*Q(5) & mask)
c |= '\040';
if (*Q(6) & mask)
c |= '\100';
if (*Q(7) & mask)
c |= '\200';
#endif
return(c);
}
/* #include "movedown.h" */
/* #include "moveover.h" */
/* #include "moveto.h" */
/* #include "nosignex.h" */
/* #include "openfont.h" */
/**********************************************************************/
/****************************** openfont ******************************/
/**********************************************************************/
void
openfont(fontname)
char *fontname;
/***********************************************************************
The original version of this DVI driver reopened the font file each
time the font changed, resulting in an enormous number of relatively
expensive file openings. This version keeps a cache of up to
MAXOPEN open files, so that when a font change is made, the file
pointer, fontfp, can usually be updated from the cache. When the
file is not found in the cache, it must be opened. In this case,
the next empty slot in the cache is assigned, or if the cache is
full, the least used font file is closed and its slot reassigned for
the new file. Identification of the least used file is based on the
counts of the number of times each file has been "opened" by this
routine. On return, the file pointer is always repositioned to the
beginning of the file.
If the first open attempt fails, an attempt will be made to use a
substitute font, then neighboring magnifications (with the same font
name), or substitutes for them.
***********************************************************************/
{
register INT16 i,j,k; /* loop indices */
INT16 current;
INT16 least_used;
INT16 maxopen = MAXOPEN;
float resfact = RESOLUTION / 200.0;
#if OS_VAXVMS
long *jpi;
#endif
struct font_entry *tfontptr;
char subfont[MAXFNAME];
int submag;
char* filelist[MAXFORMATS]; /* pointers to templist[][] */
char templist[MAXFORMATS][MAXFNAME];
#if VIRTUAL_FONTS
struct stat statbuf; /* so fstat() can get file size */
char *p;
#endif
if ((pfontptr != (struct font_entry *)NULL) && (pfontptr == fontptr))
return; /* we need not have been called */
for (j = 0; j < MAXFORMATS; ++j) /* initialize fontlist pointers */
filelist[j] = &templist[j][0];
#if IBM_PC_MICROSOFT
/* This code required rewriting to get around a fatal compiler
assertion error occasioned by the code in the #else part */
for (current = 1; current <= nopen; ++current)
{
FILE* pfp;
pfp = font_files[current].font_id;
if (pfp == fontptr->font_file_id)
break;
}
#else
for (current = 1;
(current <= nopen) &&
(font_files[current].font_id != fontptr->font_file_id);
++current)
; /* try to find file in open list */
#endif
if (current <= nopen) /* file already open, lookup its id */
fontfp = font_files[current].font_id;
else
{
/***************************************************************
The file was not in list of open files. If the list is not
full, add it to the list; otherwise close the least-used file
and remove it from the font_entry containing it. Finally, open
the file, or its closest neighbor in the magnification family.
A warning is issued if no file can be opened. The caller can
then proceed with zero font metrics if desired.
***************************************************************/
#if OS_VAXVMS
/***************************************************************
VAX VMS has many user quotas, one of which is the maximum number
of files that can be open, which need have no relation to the
number that C permits. If we do not determine the limit at
run-time, the drivers may attempt to open too many files, and in
such a case, will fail. There are two relevant quotas, FILLM
(open file limit), and FILCNT (remaining open file quota). We
use the latter, and leave one available file for a possible
error log.
***************************************************************/
jpi = (long*)getjpi(JPI$_FILCNT);
if (jpi == (long*)NULL)
maxopen = MAXOPEN; /* should never happen */
else
maxopen = nopen - 1 + *jpi;
maxopen = MIN(maxopen,MAXOPEN); /* we have arrays of size MAXFONT */
/* so do not exceed that limit */
#endif /* OS_VAXVMS */
if (nopen < maxopen) /* just add it to list */
current = ++nopen;
else /* list full -- find least used file, */
{ /* close it, and reuse slot for new file */
least_used = 1;
for (i = 2; i <= maxopen; ++i)
if (font_files[least_used].use_count >
font_files[i].use_count)
least_used = i;
fontfp = font_files[least_used].font_id;
tfontptr = hfontptr;
while (tfontptr != (struct font_entry*)NULL)
{ /* remove file pointer from its font_entry */
if (tfontptr->font_file_id == fontfp)
{
tfontptr->font_file_id = (FILE*)NULL;
break;
}
tfontptr = tfontptr->next;
}
#if VIRTUAL_FONTS
if (virt_font && (fontfp != (FILE*)NULL))
(void)virtfree(fontfp);
#endif
(void)fclose(fontfp);
fontfp = (FILE*)NULL;
current = least_used;
}
(void)actfact_res(fontptr->font_mag); /* Get global mag_index */
fontfp = (FILE*)NULL;
/***************************************************************
Try the requested font, then any substitute font, then for each
neighboring magnification from nearest to furthest, try the
requested font, and then any substitute font.
***************************************************************/
for (k = 0; (fontfp == (FILE*)NULL) && (k < MAGTABSIZE); ++k)
{ /* loop over mag family */
for (i = -k; (fontfp == (FILE*)NULL) && (i <= k); i += MAX(1,k+k))
{ /* try smaller, then larger */
if (IN(0,mag_index+i,MAGTABSIZE-1))
{
(void)fontfile(filelist, ((fontptr->a==0)?fontpath:""),
fontname, (int)MAGSIZE(mag_table[mag_index+i]*resfact));
for (j = 0; (j < MAXFORMATS) && *filelist[j]; ++j)
{
fontfp = FOPEN(filelist[j],RB_OPEN);
DEBUG_OPEN(fontfp,filelist[j],RB_OPEN);
if (fontfp != (FILE *)NULL)
{
strcpy(fontptr->name,filelist[j]);
break;
}
}
if ((k > 0) && (fontfp != (FILE*)NULL))
{
(void)sprintf(message,
"Font file [%s [mag %d]] could not be opened.\n"
"---using nearest neighbor [%s [mag %d]] instead.",
fontname,(int)MAGSIZE(mag_table[mag_index]*resfact),
fontptr->name,
(int)MAGSIZE(mag_table[mag_index+i]*resfact));
(void)warning(message);
}
if ((fontfp == (FILE*)NULL) && fontsub(subfont,&submag,
fontname,(int)MAGSIZE(mag_table[mag_index+i]*resfact)))
{
(void)fontfile(filelist,((fontptr->a==0)?fontpath:""),
subfont,(submag ? submag :
(int)MAGSIZE(mag_table[mag_index+i]*resfact)));
for (j = 0; (j < MAXFORMATS) && *filelist[j]; ++j)
{
fontfp = FOPEN(filelist[j],RB_OPEN);
DEBUG_OPEN(fontfp,filelist[j],RB_OPEN);
if (fontfp != (FILE *)NULL)
{
strcpy(fontptr->name,filelist[j]);
break;
}
}
if (fontfp != (FILE*)NULL)
{
(void)sprintf(message,
"Substituting font file [%s [mag %d]] "
"by [%s [mag %d]]",
fontname, submag,
/* (int)MAGSIZE(mag_table[mag_index]*resfact), */
fontptr->name,
(int)MAGSIZE(mag_table[mag_index+i]*resfact));
(void)warning(message);
}
}
}
} /* end for (i) -- loop over smaller and larger neighbors */
} /* end for (k) -- loop over mag family */
if (fontfp == (FILE*)NULL)
{
--nopen; /* don't count this failed open */
(void)sprintf(message,"Font file [%s [mag %d]] could not be \
opened; %d font files are open\n\
Proceeding with zero size characters for this font",
fontname,(int)MAGSIZE(mag_table[mag_index]*resfact),nopen);
(void)warning(message);
}
font_files[current].font_id = fontfp;
font_files[current].use_count = 0;
#if VIRTUAL_FONTS
/*
****************************************************************
This code is implementation-dependent. On many C compilers,
FILE points to a struct of the form
struct _iobuf {
char *_ptr; // pointer to next available char
int _cnt; // number of chars left in buffer
char *_base; // pointer to start of buffer
int _flag; // assorted flags
int _file; // file number handle
}
To implement virtual fonts, we save the pointers in a private
global array, get the file size from fstat(), malloc() a buffer
for it, read the entire file in, and replace the pointers in the
FILE variable with ones for the new buffer. Just before the
file is closed, the space is freed and the old pointers are
restored. Although many C implementations use malloc() to get
the buffer space in the first place, which would make this
saving unnecessary, not all do; see the implementation given in
Kernighan and Ritchie "The C Programming Language", p. 168.
In implementing this code on any new machine, the
implementations of fread(), read(), fseek(), and rewind() should
be checked to choose the most efficient one (e.g. one system
call for entire file read, and no double buffering), and make
sure that fseek() and rewind() do not unnecessarily discard
input buffer contents. fseek() and rewind() are defined in
terms of macros FSEEK() and REWIND() in machdefs.h to facilitate
replacement.
****************************************************************
*/
if (virt_font)
{
virt_save[fileno(fontfp)].base = (char *)NULL;
(void)fstat(fileno(fontfp),&statbuf); /* get file size */
p = (char *)MALLOC((int)statbuf.st_size); /* get file buffer */
if (p != (char *)NULL)
{
if (READ(fileno(fontfp),p,(int)statbuf.st_size)
== (int)statbuf.st_size)
{ /* read successful */
virt_save[fileno(fontfp)].ptr = FILE_PTR(fontfp);
virt_save[fileno(fontfp)].cnt = FILE_CNT(fontfp);
virt_save[fileno(fontfp)].base = FILE_BASE(fontfp);
FILE_PTR(fontfp) = p;
FILE_BASE(fontfp) = p;
FILE_CNT(fontfp) = (int)statbuf.st_size;
}
else /* failure */
{
(void)REWIND(fontfp);
(void)free(p); /* free dynamic buffer */
}
}
if (DBGOPT(DBG_FONT_CACHE))
{
(void)fprintf(stderr,"\nopenfont(): Font file %d [%s] ",
(int)fileno(fontfp),fontptr->name);
if (p == (char *)NULL)
(void)fprintf(stderr,
"cannot callocate buffer for entire file\n");
else
(void)fprintf(stderr,
"buffer length 0x%x\told buffer at 0x%lx\t\
new buffer at 0x%lx\n",
(int)statbuf.st_size,
(long)virt_save[fileno(fontfp)].base,
(long)FILE_BASE(fontfp));
}
}
#endif
} /* end if (file is in open list) */
pfontptr = fontptr; /* make previous = current font */
fontptr->font_file_id = fontfp; /* set file identifier */
font_files[current].use_count++; /* update reference count */
}
#if VIRTUAL_FONTS
void
virtfree(fp) /* free buffer space before close */
FILE *fp;
{
if (virt_font && (fp != (FILE*)NULL) &&
(virt_save[fileno(fp)].base != (char *)NULL))
{
(void)fflush(fp);
(void)free(FILE_BASE(fp));
FILE_PTR(fp) = virt_save[fileno(fp)].ptr;
FILE_CNT(fp) = virt_save[fileno(fp)].cnt;
FILE_BASE(fp) = virt_save[fileno(fp)].base;
virt_save[fileno(fp)].base = (char *)NULL;
}
}
#endif
/* #include "option.h" */
#if !OS_THINKC /* this routine is not needed in dvim72-Mac */
/*-->outline*/
/**********************************************************************/
/****************************** outline *******************************/
/**********************************************************************/
/* The name outline conflicts with a QuickDraw constant. */
#if OS_THINKC
#define outline rloutl
#endif
void
outline(pline)
char *pline;
{
register INT16 left;
register char *a,*b,*c;
INT16 len;
for ((left = XSIZE, c = pline + XSIZE - 1);
(*c == '\000') && (left > 1);
(--left,--c)) /* trim white space but leave */
; /* at least 1 character in line */
/*******************************************************************
We search for runs as follows. "b" marks the beginning of unwritten
data, and "a" anchors the beginning of a run which continues to just
before "c". The run length is "c"-"a". Since the run length
encoding carries a penalty of additional output equal to the length
of the run length prefix (<ESC>Vnnnn), short runs are not so
encoded.
If a long enough run is found, then the string "b" .. "a"-1 is
output since its length is now known, followed by the run encoding
for the character at "a". Then "a" and "b" are advanced to "c", and
the scan continues.
If the run beginning at "a" is too short, then "a" is simply
advanced.
Since the character strings take on all values on 0 .. 255, we
cannot store a termination marker, but must instead keep a counter,
"left", which is decremented to 0 when the end of the string is
reached.
?????????????xxxxxxxxxxxxxxxx????????????????????
^ ^ ^
| | |
b a c
<-----run------>
*******************************************************************/
if (runlengthcode && (left > 7))
{
for (a = b = pline; (left > 0); --left)
{
for (c = a; (*a == *++c) && left; --left)
; /* advance over run */
len = (INT16)(c-a); /* "c" points past run */
if (len > 7) /* output long run */
{
if (a > b) /* output previous string */
{
if ((int)(a-b) & 07)
OUTF("\033G%04d",(int)(a - b));
else
OUTF("\033g%03d",((int)(a - b)) >> 3);
for ( ; b < a; b++)
OUTC(*b);
}
OUTF2("\033V%04d%c",len,*a);
a = b = c;
}
else /* ignore short run */
{
++a;
left += len - 1;
}
}
if (a > b) /* output remaining string */
{
if ((int)(a-b) & 07)
OUTF("\033G%04d",(int)(a - b));
else
OUTF("\033g%03d",((int)(a - b)) >> 3);
for ( ; b < a; b++)
OUTC(*b);
}
}
else /* no runlength coding */
{
if (left & 07)
OUTF("\033G%04d",left);
else
OUTF("\033g%03d",left >> 3);
/* cannot use fprintf %s because 0 bytes terminate string */
for (c = pline; left; --left, c++)
OUTC(*c);
}
NEWLINE(plotfp);
}
#endif /* !OS_THINKC */
/* #include "outrow.h" */
/*-->prtbmap*/
/**********************************************************************/
/****************************** prtbmap *******************************/
/**********************************************************************/
void
prtbmap()
{
#if OS_THINKC
Print_page();
}
#else
register BYTE *c; /* pointer into v8[][] */
UNSIGN32 *p; /* pointer into bitmap[][] */
#if SEGMEM
#else
UNSIGN32 *ptmp; /* pointer into bitmap[][] */
#endif /* SEGMEM */
register UNSIGN32 mask; /* mask for single bit selection */
register INT16 k;
INT16 i,j,ybottom,ytop;
#if HIRES
BYTE v8[2][XSIZE]; /* vertical 8-bit raster encodings */
#undef Q
#if SEGMEM
UNSIGN32* q[16]; /* pointers to 16 raster lines */
#define Q(n) q[n] /* use precomputed pointers */
#else /* NOT SEGMEM */
#define Q(n) (p - (n)*XBIT) /* compute pointers on the fly */
#endif /* SEGMEM */
(void)clearerr(plotfp);
ytop = YBIT-1;
k = -1; /* find bottom non-zero raster */
for (j = 0; (j < ytop) && (k < 0); ++j) /* loop over raster lines */
{
#if IBM_PC_MICROSOFT
for (k = XBIT - 1; ((k >= 0) && (*BITMAP(j,k) == 0)); --k)
; /* trim white space */
#else
p = BITMAP(j,XBIT-1);
for (k = XBIT - 1; ((k >= 0) && (*p == 0)); --k)
--p; /* trim white space */
#endif /* IBM_PC_MICROSOFT */
}
ybottom = (j/16)*16 + 15;
OUTS("\033c"); /* reset printer */
(void)putc('\0', plotfp);
(void)putc('\0', plotfp);
(void)putc('\0', plotfp);
(void)putc('\0', plotfp);
(void)putc('\0', plotfp);
for (j = ytop; (j >= ybottom) ; j -= 16) /* loop over raster lines */
/* in groups of 16 */
{
#if SEGMEM
#else
p = BITMAP(j,0); /* the j-th raster line */
#endif
c = &v8[0][0]; /* vertical 8-bit encodings */
for (i = 0; i < XBIT; (++p,++i)) /* loop over raster words */
{
/* PCC-20 compiled (1 << (HOST_WORD_SIZE-1)) to 0, so do it the
hard way, arghh... */
mask = 1;
mask <<= (HOST_WORD_SIZE-1); /* to select leftmost bit */
#if SEGMEM
for (k = 0; k < 16; ++k) /* compute pointers to 16 rasters */
q[k] = BITMAP(j-k,i);
#endif /* SEGMEM */
for (k = 0; k < HOST_WORD_SIZE; (++c,++k))/* loop over word bits */
{
/* examine bits in 16 adjacent rows and build two 8-bit */
/* character values, the first with rows n,n+2,...,n+14, */
/* the second with rows n+1,n+3,...,n+15. The two */
/* characters are then printed with 1 dot vertical spacing */
#if SEGMEM
*c = (BYTE)makechar(&q[0],mask);
*(c+XSIZE) = (BYTE)makechar(&q[1],mask);
#else
*c = (BYTE)makechar(&p,mask);
ptmp = p - XBIT;
*(c+XSIZE) = (BYTE)makechar(&ptmp,mask);
#endif /* SEGMEM */
mask >>= 1; /* move masking bit right 1 position */
} /* end loop over k */
} /* end loop over i */
/* ESC p for 144 dots/inch horizontally */
/* ESC T01 for 1/144 inch spacing */
/* ESC g nnn for length/8 count */
OUTS("\033p\033T01");
(void)outline((char *)&v8[0][0]);
/* ESC p for 144 dots/inch horizontally */
/* ESC T15 for 15/144 inch spacing */
/* ESC g nnn for length/8 count */
OUTS("\033p\033T15");
(void)outline((char *)&v8[1][0]);
} /* end loop over j */
OUTC('\f'); /* eject page with FF */
OUTS("\033c"); /* reset printer */
(void)putc('\0', plotfp);
(void)putc('\0', plotfp);
(void)putc('\0', plotfp);
(void)putc('\0', plotfp);
(void)fflush(plotfp);
if (DISKFULL(plotfp))
(void)fatal("prtbmap(): Output error -- disk storage probably full");
}
#else /* NOT HIRES */
BYTE v8[XSIZE+2]; /* vertical 8-bit raster encodings */
#undef Q
#if SEGMEM
UNSIGN32* q[8]; /* pointers to 8 raster lines */
#define Q(n) q[n] /* use precomputed pointers */
#else /* NOT SEGMEM */
#define Q(n) (p - (n)*XBIT) /* compute pointers on the fly */
#endif /* SEGMEM */
ytop = YBIT-1;
k = -1; /* find bottom non-zero raster */
for (j = 0; (j < ytop) && (k < 0); ++j) /* loop over raster lines */
{
#if IBM_PC_MICROSOFT
for (k = XBIT - 1; ((k >= 0) && (*BITMAP(j,k) == 0)); --k)
; /* trim white space */
#else
p = BITMAP(j,XBIT-1);
for (k = XBIT - 1; ((k >= 0) && (*p == 0)); --k)
--p; /* trim white space */
#endif /* IBM_PC_MICROSOFT */
} /* end loop over j */
ybottom = (j/8)*8 + 7;
OUTS("\033c"); /* reset printer */
(void)putc('\0', plotfp);
(void)putc('\0', plotfp);
(void)putc('\0', plotfp);
(void)putc('\0', plotfp);
for (j = ytop; (j >= ybottom) ; j -= 8) /* loop over raster lines */
/* in groups of 8 */
{
#if SEGMEM
#else
p = BITMAP(j,0); /* the j-th raster line */
#endif /* SEGMEM */
c = &v8[0]; /* vertical 8-bit encodings */
for (i = 0; i < XBIT; (++p,++i)) /* loop over raster words */
{
/* PCC-20 compiled (1 << (HOST_WORD_SIZE-1)) to 0, so do it the
hard way, arghh... */
mask = 1;
mask <<= (HOST_WORD_SIZE-1); /* to select leftmost bit */
#if SEGMEM
for (k = 0; k < 8; ++k) /* compute pointers to 8 rasters */
q[k] = BITMAP(j-k,i);
#endif /* SEGMEM */
for (k = 0; k < HOST_WORD_SIZE; (++c,++k))/* loop over word bits */
{
/* examine bits in 8 adjacent rows and build 8-bit */
/* character value */
#if SEGMEM
*c = (BYTE)makechar(q,mask);
#else
*c = (BYTE)makechar(&p,mask);
#endif /* SEGMEM */
mask >>= 1; /* move masking bit right 1 position */
} /* end loop over k */
} /* end loop over i */
--c; /* last character encoded */
/* ESC n for 72 dots/inch horizontally */
/* ESC T16 for 16/144 inch spacing */
/* ESC G nnnn for length count */
OUTS("\033n\033T16");
(void)outline((char *)&v8[0]);
} /* end loop over j */
OUTC('\f'); /* eject page with FF */
OUTS("\033c"); /* reset printer */
(void)putc('\0', plotfp);
(void)putc('\0', plotfp);
(void)putc('\0', plotfp);
(void)putc('\0', plotfp);
(void)fflush(plotfp);
if (DISKFULL(plotfp))
(void)fatal("prtbmap(): Output error -- disk storage probably full");
}
#endif /* HIRES */
#endif /* OS_THINKC */
/* #include "prtpage.h" */
/* #include "readfont.h" */
/* #include "readgf.h" */
/* #include "readpk.h" */
/* #include "readpost.h" */
/* #include "readpxl.h" */
/* #include "reldfont.h" */
/* #include "rulepxl.h" */
/* #include "setchar.h" */
/* #include "setfntnm.h" */
/* #include "setrule.h" */
/* #include "signex.h" */
/* #include "skgfspec.h" */
/* #include "skipfont.h" */
/* #include "skpkspec.h" */
/* #include "special.h" */
/* #include "strchr.h" */
/* #include "strcm2.h" */
/* #include "strid2.h" */
/* #include "strrchr.h" */
/* #include "tctos.h" */
/* #include "usage.h" */
/* #include "warning.h" */